package biolean.commands;

import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import biolean.Biolean;
import biolean.FilterForm;
import biolean.files.Annotation;
import biolean.files.AnnotationFile;
import biolean.files.BioFile;
import biolean.logic.Pair;

/**
 * 
 * @author Erik Vir�g Trieda na funkciu Filter v projekte Biolean Funkcia
 *         dostane anotacny subor,vystupny subor a id podla coho chce filtrovat
 * 
 */ 
public class Filter extends Command
{
	public static String FILTER_SEQNAME = "SeqName";
	public static String FILTER_SOURCE 	= "Source";
	public static String FILTER_FEATURE = "Feature";
	public static String FILTER_START 	= "Start";
	public static String FILTER_END 	= "End";
	public static String FILTER_SCORE 	= "Score";
	public static String FILTER_STRAND	= "Strand";
	public static String FILTER_FRAME	= "Frame";
	
	
	private AnnotationFile inputFile;
	private AnnotationFile outputFile;
	public String mFilterSubject = null;
	public String mValue = null;
	
	
	public Filter()
	{
		insertAllowedFileType(AnnotationFile.class, BioFile.IOTYPE.INPUT, 1);
		insertAllowedFileType(AnnotationFile.class, BioFile.IOTYPE.OUTPUT, 1);
	}

	
	public static String getDescription()
	{
		return "Toto je description metody filter";
	}
	/**
	 * 
	 * @param pathInFile
	 *            - vstupny anotacny subor
	 * @param pathOutFile
	 *            - vystupny anotacny subor, uz prefiltrovany
	 * @param mFilterSubject
	 *            - podla akeho stlca sabude filtrovat
	 * @param mValue
	 *            - hodnota podla ktorej sabude filtrovat
	 * 
	 */
	
	public boolean isReady()
	{
		if (mFilterSubject == null || mValue == null )
		{
			Biolean.PrintToLog("Command filter couln't be executed because there is no filter subject");
		}
		return super.isReady() && mReady;
	}
	
	public void setArguments(String filterSubject, String value)
	{
		if ( filterSubject != "" && value != "")
		{
			mFilterSubject = filterSubject;
			mValue = value;
			setReady(true);
		}
	}
	
	public void processArguments()
	{
		if ( isReady() ) //if files and variables are ready
		{
			if (mInPuts.size() > 0)
				inputFile = (AnnotationFile)mInPuts.get(0);
			if (mConnection.size() > 0)
				outputFile =(AnnotationFile)mConnection.get(0);
			mArguments.add(new Pair<String, Object>( "mFilterSubject", (Object)mFilterSubject) );
			mArguments.add(new Pair<String, Object>( "mValue", (Object)mValue ) );
		}
	}
	
	public void loadArgument(String name, String value)
	{
		if ( name.equals( "mFilterSubject" ) ){
			mFilterSubject = value;
		}else if (name.equals( "mValue") ) {
			mValue = value == null ? null : value;
		}
	};
	
	public void run() throws IOException
	{
		inputFile.openReader();
		outputFile.openWriter();
		Annotation ann;
		List<Annotation> anns = new ArrayList<Annotation>();
		while ((ann = inputFile.readAnn()) != null)
		{
			String hodnota = null;
			// podla premenej podlaCohoSaFiltruje zistujem podla coho bude
			// fultrovat
			if (FILTER_SEQNAME.equals(mFilterSubject))
			{
				hodnota = ann.getSeqname();
			} else if (FILTER_SOURCE.equals(mFilterSubject))
			{
				hodnota = ann.getSource();
			} else if (FILTER_FEATURE.equals(mFilterSubject))
			{
				hodnota = ann.getFeature();
			} else if (FILTER_START.equals(mFilterSubject))
			{
				hodnota = Integer.toString(ann.getStart());
			} else if (FILTER_END.equals(mFilterSubject))
			{
				hodnota = Integer.toString(ann.getEnd());
			} else if (FILTER_SCORE.equals(mFilterSubject))
			{
				hodnota = Float.toString(ann.getScore());
			} else if (FILTER_STRAND.equals(mFilterSubject))
			{
				hodnota = ann.getStrand();
			} else if (FILTER_FRAME.equals(mFilterSubject))
			{
				hodnota = ann.getFrame();
			}
			// ak sa rovna ta pozadovana hodnota vybratemu stlcu zapisem do
			// vystupneho subora
			if (mValue != null && mValue != "" && mValue.equals(hodnota))
			{
				anns.add( ann );
			}
		}
		outputFile.writeFile( anns );
		
		outputFile.closeWriter();
		inputFile.closeReader();
	}
	
	public void performDoubleClick()
	{
		new FilterForm(this);
	}	
	

	public void draw(Graphics g) {
		super.draw(g);
		String valueToDraw = mValue == null ? "null" : mValue;
		String subjectToDraw = mFilterSubject== null ? "null" : mFilterSubject;
		
		
		Graphics2D g2 = (Graphics2D) g;
		FontMetrics fm = g2.getFontMetrics(BOLD_FONT);
		int textWidth = fm.stringWidth(mName);
		g2.setFont(NORMAL_FONT);
		fm = g2.getFontMetrics(NORMAL_FONT);
	    textWidth = fm.stringWidth("Value: " + valueToDraw);
		g2.drawString("Value: " + valueToDraw, x - textWidth/2, y + 15);
		textWidth = fm.stringWidth("by: " + subjectToDraw);
		g2.drawString("by: " + subjectToDraw, x - textWidth/2, y -5);
      }
}
